<?php
/**
 * @see EV_Controller_Action
 */
require_once 'Ev/Controller/Action.php';

abstract class Ev_Controller_Crud extends Ev_Controller_Action
{
    protected $_stPaginaPrincipal = 'listar';
    protected $_sRedirectGravar   = 'listar';
    protected $_sModelo;
    protected $_oModelo;
    protected $_aCamposListagem;

    /**
     * Carregar o row para passar para a view
     * @return void
     */
    public function formularioAction()
    {
        $obModelo = $this->getModelo();

        /**
         * @FIXME tratar quando não passar um id válido
         */
        if ($id = (int) $this->_request->getParam('id')) {
            $row = $obModelo->find($id)->current();
        }

        if (empty($row)) {
            $row = $obModelo->createRow();
        }

        $this->view->assign('row', $row);
        $this->_carregarExtrasFormulario();
    }

    /**
     * Carrega dados que não são do model relacionado com o controller
     * @return void
     */
    protected function _carregarExtrasFormulario()
    {
        $obModelo     = $this->getModelo();
        $this->view->assign( 'aReferencias', $obModelo->carregarArrayDadosReference() );
    }

    /**
     * Retorna o model relacionado com o controller
     * @return Ev_Db_Table
     */
    protected function getModelo()
    {
        if (empty($this->_oModelo)) {
            $sModelo = $this->_sModelo ? $this->_sModelo : $this->_getParam( 'controller' );

            $aNomeTabela = explode('-', $sModelo);
            $aFormatado  = array_map('ucFirst', $aNomeTabela);
            $sModelo     = 'Model_' . implode('', $aFormatado);

            $this->_oModelo = new $sModelo;
        }
        return $this->_oModelo;
    }

    /**
     * Grava os dados submetidos via post na tabela
     * @return void
     */
    public function gravarAction()
    {
        if ($this->_request->isPost()) {
            $oModelo = $this->getModelo();
            $aInfoExtra['oModelo'] = $oModelo;

            try {
                $this->antesGravar( $aInfoExtra );
                $id = $oModelo->gravar( $this->_getAllParams() );
                $this->posGravar( $id, $aInfoExtra );
                $this->_addMessage('Registro gravado com sucesso');
            } catch(Exception $e) {
                $this->_addMessage('Erro ao tentar gravar o registro');
                if(APPLICATION_ENV == 'development') {
                    throw $e;
                }
            }
        }
        if (!$this->getRequest()->isXmlHttpRequest()) {
            if ($this->getRequest()->getParam('module') != 'default') {
                $url = $this->getRequest()->getParam('module') . '/' . $this->getRequest()->getControllerName();
            }
            $this->_redirect($url . '/' . $this->_sRedirectGravar);
        }
        return;
    }

    /**
     * Chamado depois do gravar, pode ser utilizado para redirecionar o usuário para actions dependendo de valores
     * @param $id
     * @param array $aInfoExtra - Array de Informações Extra
     * @return void
     */
    protected function posGravar($id = null, $aInfoExtra = array()) {}

    /**
     * Chamado antes de gravar, pode ser utilizado para adicionar valores à campos pré-formatados
     * @param array $aInfoExtra - Array de Informações Extra
     * @return void
     */
    protected function antesGravar($aInfoExtra = null){}


    public function indexAction()
    {
        $this->_forward($this->_stPaginaPrincipal);
    }

    public function exportAction()
    {

    }

    /**
     * Instancia e retorna a grid para a listagem
     * @return object
     */
    protected function _getGrid()
    {
        $oModelo = $this->getModelo();

        $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/grid.ini', 'production');
        $oGrid  = Bvb_Grid::factory('Table', $config);

        $baseUrl = $this->view->baseUrl();
        $oGrid->setImagesUrl($baseUrl . '/img/bvb/');

        $sId        = $oModelo->getPrimaryKeyName();
        $sControle  = $this->getRequest()->getParam('controller');
        if ($this->getRequest()->getParam('module') != 'default') {
            $sControle = $this->getRequest()->getParam('module') . '/' . $sControle;
        }
        if (!$this->_getParam('_exportTo')) {
            $extra = new Bvb_Grid_Extra_Column();
            $extra->position ('left')
                  ->name('Ação')
                  ->decorator ('
                            <a class="ui-icon ui-icon-pencil" href="' . $baseUrl . '/'. $sControle . '/formulario/id/{{' . $sId . '}}"><span>alterar</span></a>
                            <a class="ui-icon ui-icon-close" href="' . $baseUrl . '/'. $sControle . '/excluir/id/{{' . $sId . '}}"><span>excluir</span></a>
                        ');
            $oGrid->addExtraColumns($extra);
        }
        $oGrid->setColumnsHidden(array($sId));

        $aCampos[$sId]   = $sId;
        $translate = Zend_Registry::get('Zend_Translate');
        if (!empty($this->_aCamposListagem)) {
            foreach ($this->_aCamposListagem as $sCampo) {
                $aCampos[$translate->_($sCampo)] = $sCampo;
            }
        } else {
            $sCampo = $oModelo->getCampoDescricao();
            $aCampos[$translate->_($sCampo)] = $sCampo;
        }

        $sql = $this->getSqlGrid($aCampos);
        $oGrid->setSource(new Bvb_Grid_Source_Zend_Select($sql));
        //$oGrid->query($sql);
        $oGrid->updateColumn($sId,array('hidden'=>true));

        $oGrid->setEscapeOutput(false);

        $oGrid->setExport(array('pdf'));
        $oGrid->setNumberRecordsPerPage(10);
        $oGrid = $this->extrasGrid($oGrid);
        return $oGrid;
    }

    public function getSqlGrid($aCampos)
    {
        $oModelo = $this->getModelo();
        $aTableInfo = $oModelo->info();
        $tableName  = $aTableInfo['name'];

        $oDb = Zend_Db_Table_Abstract::getDefaultAdapter();

        $sql = $oDb->select()->from($tableName, $aCampos);

        if(in_array('st_nome', $aCampos)){
            $sql->order('st_nome');
        }

        return $sql;
    }

    public function extrasGrid($oGrid)
    {
        return $oGrid;
    }

    public function listarAction()
    {
        $oGrid = $this->_getGrid();
        $this->view->assign('sGrid', $oGrid->deploy());
    }

    public function excluirAction()
    {
        if ($id = $this->_request->getParam('id')) {
            $oModelo = $this->getModelo();
            try {
                $oModelo->excluir( $id );
                $this->_addMessage('Registro apagado com sucesso');
            } catch(Exception $e) {
                $this->_addMessage('Erro ao tentar apagar o registro');
            }
        }
        $this->_redirect($this->getRequest()->getParam('module') . '/' . $this->getRequest()->getControllerName() . '/' . $this->_sRedirectGravar);
    }
}
